#define _GNU_SOURCE // 声明可以使用扩展语法
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>  // gettid()是当前库的一个扩展语法 
#include <mqueue.h>
#include <string.h>

static char *mq_name = "/mq_test";   // 路径左侧的/代表：/dev/mqueue
static mqd_t mq_fd; // 消息队列文件描述符

// first线程的线程函数
void *first_thread_fun(void *arg) {  // 发消息
    sleep(3);
    printf("first线程开始执行，准备发消息 \n");

    char *msg = "hello";
    mq_send(mq_fd, msg, strlen(msg)+1, 0);
    printf("first线程发送消息成功 \n");

    return NULL;
}

// second线程的线程函数
void *second_thread_fun(void *arg) { // 接收消息
    // sleep(3);
    printf("second线程开始执行，准备收消息 \n");
    char msg_buf[100];
    ssize_t len = mq_receive(mq_fd, msg_buf, 100, NULL); // 阻塞式的：如果没有消息，则一直等待
    printf("second线程接收到消息：%s, len=%ld \n", msg_buf, len);

    return NULL;
}

int main(int argc, char const *argv[])
{
    // 创建消息队列
    struct mq_attr attr;
    attr.mq_maxmsg = 10; // 消息队列中最大消息数
    attr.mq_msgsize = 100; // 每条消息的最大字节数

    mq_fd = mq_open(mq_name, O_CREAT|O_RDWR, 0644, &attr);
    if (mq_fd == -1) {
        printf("创建打开消息队列失败 \n");
        return -1;
    }

    // 创建2个分线程
    pthread_t pt1, pt2;
    pthread_create(&pt1, NULL, first_thread_fun, NULL);
    pthread_create(&pt2, NULL, second_thread_fun, NULL);
    //等待分线程结束
    pthread_join(pt1, NULL);
    pthread_join(pt2, NULL);

    // 关闭消息队列， 删除队列
    mq_close(mq_fd);
    mq_unlink(mq_name);

    return 0; 
}
